/**
 * GeneralSystemMessageDispatcher.java
 * ************************** 
 * @date Apr 18, 2011
 * @author Michele Tamburini
 * 
 * **************************
 */
package systems.network;


import infrastructureAPI.APIMessages.RequestMessage;
import infrastructureAPI.algorithms.APIFunction;

import java.util.ArrayDeque;
import java.util.Queue;

import networkRmi.NetworkManager;

import messages.Message;

/**
 * Description: 
 * This class extends the {@link GeneralSystemsNetManager} and implements
 * the {@link RequestUnmarshalling}. It's able to manage the incoming
 * messages of the {@link NetworkManager} and dispatch them into 
 * the message queue of the system object. 
 * It implements the method extractIncomingMessages(Queue<<Message>).
 * For its construction it needs the {@link NetworkManager} and the 
 * Class<?> type of the messages to be extracted from the NetworkManager
 * message queue.  
 *
 */
public class GeneralSystemsMessageDispatcher extends GeneralSystemsNetManager
	implements RequestUnmarshalling{
	
	protected Class<?> messageClass;
	protected Queue<Message> rawReceivedMessages = new ArrayDeque<Message>(200);
	
	/**
	 * @param netMan
	 */
	public GeneralSystemsMessageDispatcher(NetworkManager netMan,
			Class<?> incomingMsgClass) {
		super(netMan);
		this.messageClass = incomingMsgClass;
	}

	@Override
	public void extractIncomingMessages(Queue<Message> queue) {
		boolean notify = false;
		int size = queue.size();
		for(int i=0; i<size;i++){
			Message m = queue.poll();
			if(m.getClass().equals(messageClass)){
				rawReceivedMessages.add(m);
				//@ For Debug
//				System.out.println(Thread.currentThread().getName()+
//						" found message: "+m);
			}else{
				queue.add(m);
			}			
		}
		
		synchronized (receivedSystemMessages) {
			Message m ;
			notify = (!rawReceivedMessages.isEmpty());
			while(!rawReceivedMessages.isEmpty()){
				m = rawReceivedMessages.poll();
				receivedSystemMessages.add(m);				
			}
			if(notify)				
				receivedSystemMessages.notify();
		}

	}

	@Override
	public APIFunction unmarshalRequestMessage(RequestMessage reqMsg) {
		return reqMsg.getFunction();
	}

	public Queue<Message> getIncomingMessageQueue() {
		return rawReceivedMessages;
	}

}
